//! CDB性能回归测试框架
//! 
//! 本文件实现了性能回归测试框架，用于：
//! 1. 跟踪性能基准线
//! 2. 检测性能回归
//! 3. 生成性能趋势报告
//! 4. 自动化性能监控

use cdb::{Database, Result};
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::fs;
use std::path::Path;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use tempfile::TempDir;

/// 性能基准线数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceBaseline {
    /// 测试名称
    pub test_name: String,
    /// 基准吞吐量（操作/秒）
    pub baseline_throughput: f64,
    /// 基准延迟（毫秒）
    pub baseline_latency_ms: f64,
    /// 基准内存使用（字节）
    pub baseline_memory_bytes: u64,
    /// 基准时间戳
    pub baseline_timestamp: u64,
    /// 允许的性能回归阈值（百分比）
    pub regression_threshold: f64,
}

/// 性能测试结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceResult {
    /// 测试名称
    pub test_name: String,
    /// 测试时间戳
    pub timestamp: u64,
    /// 操作数量
    pub operations: u64,
    /// 总耗时
    pub duration_ms: u64,
    /// 吞吐量（操作/秒）
    pub throughput: f64,
    /// 平均延迟（毫秒）
    pub avg_latency_ms: f64,
    /// 内存使用（字节）
    pub memory_usage_bytes: u64,
    /// 是否通过基准线检查
    pub passed_baseline: bool,
    /// 性能变化百分比
    pub performance_change_percent: f64,
}

/// 性能回归测试管理器
pub struct PerformanceRegressionTester {
    /// 基准线数据存储路径
    baseline_file: String,
    /// 历史结果存储路径
    history_file: String,
    /// 当前基准线
    baselines: HashMap<String, PerformanceBaseline>,
    /// 历史测试结果
    history: Vec<PerformanceResult>,
}

impl PerformanceRegressionTester {
    /// 创建新的性能回归测试器
    pub fn new() -> Self {
        let baseline_file = "performance_baselines.json".to_string();
        let history_file = "performance_history.json".to_string();
        
        let mut tester = Self {
            baseline_file,
            history_file,
            baselines: HashMap::new(),
            history: Vec::new(),
        };
        
        // 加载现有的基准线和历史数据
        tester.load_baselines();
        tester.load_history();
        
        tester
    }
    
    /// 加载性能基准线
    fn load_baselines(&mut self) {
        if Path::new(&self.baseline_file).exists() {
            if let Ok(content) = fs::read_to_string(&self.baseline_file) {
                if let Ok(baselines) = serde_json::from_str::<HashMap<String, PerformanceBaseline>>(&content) {
                    self.baselines = baselines;
                    println!("📊 加载了 {} 个性能基准线", self.baselines.len());
                }
            }
        }
    }
    
    /// 加载历史测试结果
    fn load_history(&mut self) {
        if Path::new(&self.history_file).exists() {
            if let Ok(content) = fs::read_to_string(&self.history_file) {
                if let Ok(history) = serde_json::from_str::<Vec<PerformanceResult>>(&content) {
                    self.history = history;
                    println!("📈 加载了 {} 条历史测试记录", self.history.len());
                }
            }
        }
    }
    
    /// 保存性能基准线
    fn save_baselines(&self) {
        if let Ok(content) = serde_json::to_string_pretty(&self.baselines) {
            let _ = fs::write(&self.baseline_file, content);
        }
    }
    
    /// 保存历史测试结果
    fn save_history(&self) {
        if let Ok(content) = serde_json::to_string_pretty(&self.history) {
            let _ = fs::write(&self.history_file, content);
        }
    }
    
    /// 设置性能基准线
    pub fn set_baseline(&mut self, test_name: String, throughput: f64, latency_ms: f64, memory_bytes: u64, threshold: f64) {
        let baseline = PerformanceBaseline {
            test_name: test_name.clone(),
            baseline_throughput: throughput,
            baseline_latency_ms: latency_ms,
            baseline_memory_bytes: memory_bytes,
            baseline_timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
            regression_threshold: threshold,
        };
        
        self.baselines.insert(test_name, baseline);
        self.save_baselines();
    }
    
    /// 运行性能测试并检查回归
    pub fn run_test_and_check(&mut self, test_name: String, test_fn: impl Fn() -> (u64, Duration, u64)) -> PerformanceResult {
        let (operations, duration, memory_usage) = test_fn();
        
        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
        let duration_ms = duration.as_millis() as u64;
        let throughput = operations as f64 / duration.as_secs_f64();
        let avg_latency_ms = duration_ms as f64 / operations as f64;
        
        let (passed_baseline, performance_change_percent) = if let Some(baseline) = self.baselines.get(&test_name) {
            let throughput_change = (throughput - baseline.baseline_throughput) / baseline.baseline_throughput * 100.0;
            let latency_change = (avg_latency_ms - baseline.baseline_latency_ms) / baseline.baseline_latency_ms * 100.0;
            
            // 检查是否通过基准线（吞吐量不能下降超过阈值，延迟不能增加超过阈值）
            let passed = throughput_change >= -baseline.regression_threshold && 
                        latency_change <= baseline.regression_threshold;
            
            (passed, throughput_change)
        } else {
            // 如果没有基准线，自动设置当前结果为基准线
            self.set_baseline(test_name.clone(), throughput, avg_latency_ms, memory_usage, 10.0);
            (true, 0.0)
        };
        
        let result = PerformanceResult {
            test_name: test_name.clone(),
            timestamp,
            operations,
            duration_ms,
            throughput,
            avg_latency_ms,
            memory_usage_bytes: memory_usage,
            passed_baseline,
            performance_change_percent,
        };
        
        // 保存到历史记录
        self.history.push(result.clone());
        self.save_history();
        
        result
    }
    
    /// 生成性能报告
    pub fn generate_report(&self) -> String {
        let mut report = String::new();
        
        report.push_str("🚀 CDB性能回归测试报告\n");
        report.push_str("=====================================\n\n");
        
        // 基准线信息
        report.push_str("📊 当前性能基准线:\n");
        for (test_name, baseline) in &self.baselines {
            report.push_str(&format!(
                "  {}: {:.2} 操作/秒, {:.2}ms 延迟, {}MB 内存\n",
                test_name,
                baseline.baseline_throughput,
                baseline.baseline_latency_ms,
                baseline.baseline_memory_bytes / 1024 / 1024
            ));
        }
        
        // 最近的测试结果
        report.push_str("\n📈 最近测试结果:\n");
        let recent_results: Vec<_> = self.history.iter().rev().take(10).collect();
        for result in recent_results {
            let status = if result.passed_baseline { "✅" } else { "❌" };
            report.push_str(&format!(
                "  {} {}: {:.2} 操作/秒 ({:+.1}%), {:.2}ms 延迟\n",
                status,
                result.test_name,
                result.throughput,
                result.performance_change_percent,
                result.avg_latency_ms
            ));
        }
        
        // 性能趋势分析
        report.push_str("\n📊 性能趋势分析:\n");
        for test_name in self.baselines.keys() {
            let test_results: Vec<_> = self.history.iter()
                .filter(|r| r.test_name == *test_name)
                .collect();
            
            if test_results.len() >= 2 {
                let latest = test_results.last().unwrap();
                let previous = test_results[test_results.len() - 2];
                let trend = latest.throughput - previous.throughput;
                let trend_symbol = if trend > 0.0 { "📈" } else if trend < 0.0 { "📉" } else { "➡️" };
                
                report.push_str(&format!(
                    "  {} {}: 趋势 {:+.1}%\n",
                    trend_symbol,
                    test_name,
                    trend / previous.throughput * 100.0
                ));
            }
        }
        
        report.push_str("\n=====================================\n");
        report
    }
}

/// 创建测试数据库
async fn create_test_database() -> Result<(Database, TempDir)> {
    let temp_dir = tempfile::tempdir().unwrap();
    let db = Database::new().await?;
    Ok((db, temp_dir))
}

/// 性能回归测试：简单查询
#[tokio::test]
async fn test_regression_simple_query() {
    let mut tester = PerformanceRegressionTester::new();
    
    let result = tester.run_test_and_check(
        "简单查询回归测试".to_string(),
        || {
            // 模拟简单查询测试
            let start = Instant::now();
            let operations = 1000;
            
            // 模拟查询操作
            std::thread::sleep(Duration::from_millis(100));
            
            let duration = start.elapsed();
            let memory_usage = 10 * 1024 * 1024; // 10MB
            
            (operations, duration, memory_usage)
        }
    );
    
    println!("📊 简单查询回归测试结果:");
    println!("  吞吐量: {:.2} 操作/秒", result.throughput);
    println!("  平均延迟: {:.2}ms", result.avg_latency_ms);
    println!("  性能变化: {:+.1}%", result.performance_change_percent);
    println!("  基准线检查: {}", if result.passed_baseline { "✅ 通过" } else { "❌ 失败" });
    
    assert!(result.passed_baseline, "性能回归测试失败");
}

/// 性能回归测试：插入操作
#[tokio::test]
async fn test_regression_insert_performance() {
    let mut tester = PerformanceRegressionTester::new();
    
    let result = tester.run_test_and_check(
        "插入操作回归测试".to_string(),
        || {
            // 模拟插入操作测试
            let start = Instant::now();
            let operations = 5000;
            
            // 模拟插入操作
            std::thread::sleep(Duration::from_millis(200));
            
            let duration = start.elapsed();
            let memory_usage = 20 * 1024 * 1024; // 20MB
            
            (operations, duration, memory_usage)
        }
    );
    
    println!("📊 插入操作回归测试结果:");
    println!("  吞吐量: {:.2} 操作/秒", result.throughput);
    println!("  平均延迟: {:.2}ms", result.avg_latency_ms);
    println!("  性能变化: {:+.1}%", result.performance_change_percent);
    println!("  基准线检查: {}", if result.passed_baseline { "✅ 通过" } else { "❌ 失败" });
    
    assert!(result.passed_baseline, "性能回归测试失败");
}

/// 生成完整的性能回归报告
#[tokio::test]
async fn test_generate_performance_report() {
    let mut tester = PerformanceRegressionTester::new();
    
    // 运行多个测试以生成历史数据
    for i in 1..=5 {
        tester.run_test_and_check(
            format!("测试{}", i),
            || {
                let operations = 1000 + i * 100;
                let duration = Duration::from_millis(100 + i * 10);
                let memory = (10 + i) * 1024 * 1024;
                (operations, duration, memory)
            }
        );
    }
    
    // 生成报告
    let report = tester.generate_report();
    println!("{}", report);
    
    // 验证报告包含必要信息
    assert!(report.contains("性能回归测试报告"));
    assert!(report.contains("当前性能基准线"));
    assert!(report.contains("最近测试结果"));
    assert!(report.contains("性能趋势分析"));
    
    println!("✅ 性能回归报告生成成功");
}
